package com.luo.sc.oidc.authserver.handler.kapatcha;

import com.luo.sc.oidc.authserver.handler.login.UniLoginUserDetails;
import com.luo.sc.oidc.authserver.handler.login.UniLoginUserDetailsPasswordMatcherService;
import com.luo.sc.oidc.authserver.utils.HttpContextUtils;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 验证码登录 - 用户查询及认证服务 - 账号、密码、验证码验证实现<br/>
 *
 * @author luohq
 * @version 1.0.0
 * @date 2022-03-03
 */
@Component
public class UniLoginUserDetailsKaptchaMatcherService extends UniLoginUserDetailsPasswordMatcherService {
    /**
     * 登录表单常量定义
     */
    private static final String CAPTCHA_PARAMETER = "captcha";

    /**
     * Kapatcha生成器
     */
    private DelegatingKapatchaProducer delegatingKapatchaProducer;

    public UniLoginUserDetailsKaptchaMatcherService(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder, DelegatingKapatchaProducer delegatingKapatchaProducer) {
        super(userDetailsService, passwordEncoder);
        this.delegatingKapatchaProducer = delegatingKapatchaProducer;
    }

    @Override
    public UniLoginUserDetails loadUserByAuthParams(Map<String, String> authParams) throws UsernameNotFoundException {
        //验证码参数验证
        this.validateAuthParams(authParams);
        //使用父类查询用户
        return super.loadUserByAuthParams(authParams);
    }


    @Override
    public void authenticateUser(Map<String, String> authParams, UniLoginUserDetails uniLoginUserDetails) throws AuthenticationException {
        //调用父类用户名、密码验证
        super.authenticateUser(authParams, uniLoginUserDetails);
        //验证验证码是否匹配
        Boolean isVerifiedKaptcha = this.delegatingKapatchaProducer.verifyKaptchaResultText(authParams.get(CAPTCHA_PARAMETER),
                HttpContextUtils.getRequest(), HttpContextUtils.getResponse());
        if (!isVerifiedKaptcha) {
            throw new BadCredentialsException("验证码无效");
        }
    }

    /**
     * 验证认证参数（是否包含对应参数）
     *
     * @param authParams 认证参数
     */
    private void validateAuthParams(Map<String, String> authParams) {
        //验证账号、密码相关表单参数非空
        if (!authParams.containsKey(CAPTCHA_PARAMETER)) {
            throw new UsernameNotFoundException("验证码为空");
        }
    }

}
